/**
 * 
 */
package neptune.web.client.view.components.dialogs;

import neptune.web.client.view.input.DefaultInputValidator;
import neptune.web.client.view.input.EmailValidator;
import neptune.web.client.view.input.InputValidator;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * This class implements an AddUser dialog, with these elements:
 * 
 * <ul>
 * <li>usernaname</li>
 * <li>password</li>
 * <li>e-mail</li>
 * <li>role</li>
 * </ul>
 * 
 * Two different InputValidators are used to validate username/password and e-mail.<br/>
 * To listen from this interface, you must register an AddUserPanelListener.
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * @see neptune.web.client.view.components.dialogs.AddUserDialogListener
 * 
 */
public class AddUserDialog extends DialogBox implements ClickListener {

	private TextBox username = new TextBox();
	private TextBox password = new TextBox();
	private InputValidator generalValidator = new DefaultInputValidator();
	private TextBox email = new TextBox();
	private InputValidator emailValidator = new EmailValidator();
	private ListBox role = new ListBox();
	
	private AddUserDialogListener listener;
	private DeckPanel mainPanelWrap;
	private Label messageLabel;

	/**
	 * Builds the interface 
	 * 
	 * @param roles a String array that rapresents the roles that are shown in the ListBox
	 * @param listener The interface listener
	 */
	public AddUserDialog(String[] roles, AddUserDialogListener listener) {
		super(false, true);

		this.listener = listener;
		VerticalPanel mainPanel = new VerticalPanel();

		Label usernameLabel = new Label("Username");
		Label passwordLabel = new Label("Password");
		Label emailLabel = new Label("e-mail");
		Label roleLabel = new Label("Role");

		HorizontalPanel usernamePanel = new HorizontalPanel();
		usernamePanel.add(usernameLabel);
		usernamePanel.add(username);

		HorizontalPanel passwordPanel = new HorizontalPanel();
		passwordPanel.add(passwordLabel);
		passwordPanel.add(password);

		HorizontalPanel emailPanel = new HorizontalPanel();
		emailPanel.add(emailLabel);
		emailPanel.add(email);

		HorizontalPanel rolePanel = new HorizontalPanel();
		rolePanel.add(roleLabel);
		rolePanel.add(role);

		Button okButton = new Button("Ok");
		okButton.addClickListener(this);
		Button cancelButton = new Button("Cancel");
		cancelButton.addClickListener(this);

		HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.add(okButton);
		buttonPanel.add(cancelButton);

		FlowPanel infoPanel = new FlowPanel();
		
		infoPanel.add(usernamePanel);
		infoPanel.add(passwordPanel);
		infoPanel.add(emailPanel);
		infoPanel.add(rolePanel);
		
		mainPanel.add(infoPanel);
		mainPanel.add(buttonPanel);
		mainPanel.setCellHorizontalAlignment(buttonPanel,
				VerticalPanel.ALIGN_RIGHT);
		
		mainPanelWrap = new DeckPanel();
		mainPanelWrap.add(mainPanel);
		mainPanelWrap.add(buildProcessingView());
		mainPanelWrap.add(buildMessagePanel());

		mainPanelWrap.showWidget(0);
		this.setWidget(mainPanelWrap);
		this.setText("Add User Window");
		this.setRoles(roles);

		// Styles
		this.setStyleName("AddUserPanel");

		usernameLabel.setStyleName("AddUserPanel-labels");
		passwordLabel.setStyleName("AddUserPanel-labels");
		emailLabel.setStyleName("AddUserPanel-labels");
		roleLabel.setStyleName("AddUserPanel-labels");

		username.setStyleName("AddUserPanel-inputs");
		password.setStyleName("AddUserPanel-inputs");
		email.setStyleName("AddUserPanel-inputs");
		role.setStyleName("AddUserPanel-inputs");

		infoPanel.setStyleName("AddUserPanel-infoPanel");
		
		okButton.setStyleName("AddUserPanel-buttons");
		cancelButton.setStyleName("AddUserPanel-buttons");
	}

	/**
	 * Returns the username actual value
	 * 
	 * @return
	 */
	public String getUsername() {
		return username.getText();
	}

	/**
	 * Returns the password actual value
	 * 
	 * @return
	 */
	public String getPassword() {
		return password.getText();
	}

	/**
	 * Returns the email actual value
	 * 
	 * @return
	 */
	public String getEmail() {
		return email.getText();
	}

	/**
	 * Returns the role actual selected value
	 * 
	 * @return
	 */
	public String getRole() {
		return role.getItemText(role.getSelectedIndex());
	}

	/**
	 * Sets the role choiches
	 * 
	 * @param roles a string array
	 */
	public void setRoles(String[] roles) {
		for (int i = 0; i < roles.length; i++) {
			role.addItem(roles[i]);
		}
	}

	/**
	 * This method listens for click events on this interface's buttons
	 * 
	 */
	public void onClick(Widget sender) {
		if (((Button) sender).getText().equals("Ok")) {
			boolean error = false;
			username.setStyleName("AddUserPanel-inputs");
			password.setStyleName("AddUserPanel-inputs");
			email.setStyleName("AddUserPanel-inputs");
			
			if (!generalValidator.isValid(getUsername())){
				error = true;
				username.addStyleName("AddUserPanel-inputs-err");
			}
			if (!generalValidator.isValid(getPassword())){
				error = true;
				password.addStyleName("AddUserPanel-inputs-err");
			}
			if (!emailValidator.isValid(getEmail())){
				error = true;
				email.addStyleName("AddUserPanel-inputs-err");
			}
			
			if(!error){
				mainPanelWrap.showWidget(1);
				listener.addUserCommandGiven(getUsername(), getPassword(),
						getEmail(), getRole(), this);
				return;
			}else
				return;
				
		}

		this.hide();
		resetWindow();
	}
	
	private void resetWindow(){
		mainPanelWrap.showWidget(0);
		username.setText("");
		password.setText("");
		email.setText("");
		role.setSelectedIndex(0);
	}

	/**
	 * Gets the input validator for username and password
	 * 
	 * @return
	 */
	public InputValidator getGeneralValidator() {
		return generalValidator;
	}

	/**
	 * Sets the input validator for username and password
	 * 
	 * @return
	 */
	public void setGeneralValidator(InputValidator generalValidator) {
		this.generalValidator = generalValidator;
	}

	/**
	 * Gets the input validator for email
	 * 
	 * @return
	 */
	public InputValidator getEmailValidator() {
		return emailValidator;
	}

	/**
	 * Sets the input validator for email
	 * 
	 * @return
	 */
	public void setEmailValidator(InputValidator emailValidator) {
		this.emailValidator = emailValidator;
	}
	
	/**
	 * Sets which of the inputs must be set to error style
	 * 
	 * @param usernameInput true to set username to error style
	 * @param passwordInput true to set password to error style
	 * @param emailInput true to set email to error style
	 */
	public void setInputErrors(boolean usernameInput, boolean passwordInput, boolean emailInput){
		if (usernameInput){
			username.addStyleName("AddUserPanel-inputs-err");
		}
		if (passwordInput){
			password.addStyleName("AddUserPanel-inputs-err");
		}
		if (emailInput){
			email.addStyleName("AddUserPanel-inputs-err");
		}
	}
	
	private Panel buildProcessingView(){
		Image loading = new Image("img/bigrotation2.gif");
		Label loadingLabel = new Label("Processing request...");
		
		VerticalPanel panel = new VerticalPanel();
		
		panel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		
		panel.add(loading);
		panel.add(loadingLabel);
		
		panel.setStyleName("AddUserPanel-processingPanel");
		
		return panel;
	}
	
	/**
	 * Sets the processing view as the active/deactive view of this interface
	 * 
	 * @param isProcessing true to set the processing view
	 */
	public void setProcessing(boolean isProcessing){
		if(isProcessing)
			mainPanelWrap.showWidget(1);
		else
			mainPanelWrap.showWidget(0);
	}
	
	private Panel buildMessagePanel(){
		VerticalPanel panel = new VerticalPanel();
		
		messageLabel = new Label();
		Button close = new Button("Close");
		close.addClickListener(this);
		
		panel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		
		panel.add(messageLabel);
		panel.add(close);
		
		panel.setStyleName("AddUserPanel-messagePanel");
		
		return panel;
	}

	/**
	 * Sets the message view as the active view and shown the given message
	 * 
	 * @param message
	 */
	public void showMessage(String message){
		messageLabel.setText(message);
		messageLabel.setWidth(Integer.toString(mainPanelWrap.getOffsetWidth()-20));
		mainPanelWrap.showWidget(2);
	}
}
